package studystat;

import java.util.ArrayList;
import java.util.List;
import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.PreparedQuery;
import com.google.appengine.api.datastore.Query;
import java.util.Calendar;
import java.util.Date;

public class StudentManager {

	private List<Student> students;

	private DatastoreService datastore;

	private static StudentManager instance = null;

	private StudentManager() {
		datastore = DatastoreServiceFactory.getDatastoreService();
		students = new ArrayList<Student>();
		//We halen alle geregistreerde Studenten uit de datastore en maken er een lijst van zodat we tijdens het programma kunnen werken mbv 
		//een lijst.
		Query q = new Query("Student");
		q.addFilter("GoogleAccount", Query.FilterOperator.NOT_EQUAL, null);
		PreparedQuery pq = datastore.prepare(q);
		for (Entity result : pq.asIterable()) {
			String achternaam = (String) result.getProperty("Achternaam");
			String voornaam = (String) result.getProperty("Voornaam");
			String googleAccount = (String) result.getProperty("GoogleAccount");
			Student theStudent = new Student(achternaam, voornaam,googleAccount);
			List<String> vakkenString = new ArrayList<String>();
			int k = 0;
			int i = 0;
			while (k != 1) {
				if (result.getProperty("Vak" + i) == null) {
					k = 1;
				} else {
					String vak = (String) result.getProperty("Vak" + i);
					vakkenString.add(vak);
				}
				i++;
			}
			List<Vak> vakken = new ArrayList<Vak>();
			for (int j = 0; j < vakkenString.size(); j++) {
				vakken.add(VakManager.getInstance().getVak(vakkenString.get(j)));
			}
			theStudent.setVakken(vakken);
			students.add(theStudent);
			}
			//We halen alle activiteiten uit de datastore en steken dit in de activiteitenlijst van de student.
			Query q1 = new Query("Activiteit");
			for(int j = 0; j< students.size(); j++){
				q1.addFilter("Student", Query.FilterOperator.EQUAL, students.get(j).getGoogleAccount());
				PreparedQuery pq1 = datastore.prepare(q1);
				for (Entity result1 : pq1.asIterable()) {
					String type = (String) result1.getProperty("Type");
					
				
					if(type != null){
						if(type.equals("studie")){
							Studie studie = new Studie();
							studie.setGestopt((Boolean) result1.getProperty("Gestopt"));
							if((Boolean) result1.getProperty("Gestopt")){
								studie.setAantalOef((Long) result1.getProperty("AantalOef"));
								studie.setAantalPag((Long) result1.getProperty("AantalPag"));
								studie.setOefeningen((Boolean) result1.getProperty("Oefeningen"));
								studie.setTheorie((Boolean) result1.getProperty("Theorie"));
								studie.setStopTijd((Date) result1.getProperty("Stoptijd"));
								studie.setRating((Long) result1.getProperty("Rating"));
							}
							studie.setPlaats((String) result1.getProperty("Plaats"));
							studie.setSamen((Boolean) result1.getProperty("Samen"));
							studie.setStartTijd((Date) result1.getProperty("Starttijd"));
							studie.setVak(VakManager.getInstance().getVak((String) result1.getProperty("Vak")));
							if(result1.getProperty("BeginLaatsePauze") !=null){
								studie.setBeginLaatstePauze((Date) result1.getProperty("BeginLaatstePauze"));
							}
							studie.setPauzeDuur((Long) result1.getProperty("PauzeDuur"));
							getStudent(students.get(j).getGoogleAccount()).addActiviteit(studie);
						}
						else if(type.equals("sport")){
							Sport sport = new Sport();
							sport.setGestopt((Boolean) result1.getProperty("Gestopt"));
							if((Boolean) result1.getProperty("Gestopt")){
								sport.setRating((Long) result1.getProperty("Rating"));
								sport.setStopTijd((Date) result1.getProperty("Stoptijd"));
							}
							
							sport.setStartTijd((Date) result1.getProperty("Starttijd"));
							if(result1.getProperty("PauzeDuur")!=null){
								sport.setBeginLaatstePauze((Date) result1.getProperty("BeginLaatstePauze"));
							}
							sport.setPauzeDuur((Long) result1.getProperty("PauzeDuur"));
							getStudent(students.get(j).getGoogleAccount()).addActiviteit(sport);//getActiviteiten().add(sport);
						}
						else if(type.equals("slaap")){
							Slaap slaap = new Slaap();
							slaap.setRating((Long) result1.getProperty("Rating"));
							slaap.setDuur((Long) result1.getProperty("Duur"));
							getStudent(students.get(j).getGoogleAccount()).addActiviteit(slaap);//getActiviteiten().add(slaap);
						}
					}
				}
		}
			//zet alle behaalde achievements van alle student in een arraylist van de bijbehorende student
			Query q2 = new Query("BehaaldeAchievement");
			for (int k =0; k<students.size(); k++){
				List<Achievement> achievements = new ArrayList<Achievement>();
				q2.addFilter("Student", Query.FilterOperator.EQUAL, students.get(k).getGoogleAccount());
				PreparedQuery pq2 = datastore.prepare(q2);
				for (Entity result2 : pq2.asIterable()) {
					Achievement achievement = new Achievement((String) result2.getProperty("Naam"));
					achievement.setTitel((String) result2.getProperty("Titel"));
					List<Conditie> condities = new ArrayList<Conditie>();
					UrenConditie conditie = new UrenConditie ((String) result2.getProperty("Naam"),(Long) result2.getProperty("InHoeveelTijd"),(Long) result2.getProperty("UrenNodig"));
					condities.add(conditie);
					achievement.setCondities(condities);
				}
				getStudent(students.get(k).getGoogleAccount()).setAchievements(achievements);
			}	
	}

	public static StudentManager getInstance() {
		if (instance == null) {
			instance = new StudentManager();
		}
		return instance;
	}

	/**
	 * private void initializeData(){ int i = 0; while(i<students.size()) {
	 * Entity student = new Entity("Student"); student.setProperty("Achternaam",
	 * students.get(i).getAchternaam()); student.setProperty("Voornaam",
	 * students.get(i).getVoornaam()); student.setProperty("ISP",
	 * students.get(i).getVakken()); student.setProperty("Activiteiten",
	 * students.get(i).getActiviteiten()); student.setProperty("Achievements",
	 * students.get(i).getAchievements()); student.setProperty("GoogleAccount",
	 * students.get(i).getGoogleAccount()); datastore.put(student); i++; } }
	 * 
	 * @return
	 */

	public Student getStudent(String googleAccount) {
		Student theStudent = null;
		for(int i =0; i<students.size(); i++){
			if(students.get(i).getGoogleAccount().equals(googleAccount)){
				theStudent = students.get(i);
			}
		}
		return theStudent;
	}
	
	/**
	 * was mbv de datastore --> nu met lijst (wordt toch ingeladen bij begin programma)!!!!
	 * @param voornaam
	 * @param achternaam
	 * @param googleAccount
	 * @param vakken
	 */

	public void register(String voornaam, String achternaam,
			String googleAccount, List<Vak> vakken) {
		// methode werkt blijkbaar niet! --> geeft errors in 2 lijnen
		// registercontroller!
		Student studentje = new Student(achternaam, voornaam, googleAccount);
		studentje.setVakken(vakken);
		students.add(studentje);
		Entity student = new Entity("Student");
		student.setProperty("Achternaam", achternaam);
		student.setProperty("Voornaam", voornaam);
		for (int i = 0; i < vakken.size(); i++) {
			student.setProperty("Vak" + i, vakken.get(i).getNaam());
		}
		student.setProperty("GoogleAccount", googleAccount);
		datastore.put(student);
	}

	public List<Student> getStudents() {
		return students;
	}

	public List<String> getVakkenVanStudent(String googleAccount) {
		// deze methode geeft de vakken van een bepaalde student terug
		// Student theStudent = getStudent(googleAccount);
		List<String> vakken = new ArrayList<String>();
		Query q = new Query("Student");
		int k = 0;
		int i = 0;
		while (k < 1) {
			for (int j = 0; j < VakManager.getInstance().getVakken().size(); j++) {
				q.addFilter("Vak" + i, Query.FilterOperator.EQUAL, VakManager
						.getInstance().getVakken().get(j));
				PreparedQuery pq = datastore.prepare(q);
				for (Entity result : pq.asIterable()) {
					if (result == null) {
						k = 1;
					}
					q.addFilter("GoogleAccount", Query.FilterOperator.EQUAL,
							googleAccount);
					PreparedQuery pq1 = datastore.prepare(q);
					for (Entity result1 : pq1.asIterable()) {
						int r = 0;
						// }
						// assert( result != null );
						// for (Entity result : pq.asIterable()) {
						int k1 = 0;
						int i1 = 0;
						while (k1 != 1) {
							if (result1.getProperty("Vak" + i) == null) {
								k1 = 1;
							} else {
								String hetVak = (String) result1
										.getProperty("Vak" + i);
								vakken.add(hetVak);
							}
						}
						i1++;
					}
					// }

				}
			}
		}
		return vakken;
	}

	public DatastoreService getDataStore() {
		return datastore;
	}

	public boolean isRegistered(String googleAccount) {
		boolean answer = false;
		for (int i = 0; i < students.size(); i++) {
			String testGoogleAccountvanStudent = students.get(i)
					.getGoogleAccount();
			if (students.get(i).getGoogleAccount().equals(googleAccount)) {
				answer = true;
			}
		}
		return answer;
	}

	public void createStudie(String googleAccount, Date starttijd, String type,
			String vak, boolean samen, String plaats) {
		Studie studie = new Studie();
		studie.setStartTijd(starttijd);
		studie.setVak(VakManager.getInstance().getVak(vak));
		studie.setSamen(samen);
		studie.setPlaats(plaats);
		getStudent(googleAccount).addActiviteit((Activiteit) studie);
		Entity activiteit = new Entity("Activiteit");
			activiteit.setProperty("Type", type);
			activiteit.setProperty("Vak", vak);
			activiteit.setProperty("Starttijd", starttijd);
			activiteit.setProperty("Gestopt", false);
			activiteit.setProperty("Student", googleAccount);
			activiteit.setProperty("Plaats", plaats);
			activiteit.setProperty("Samen", samen);
			activiteit.setProperty("PauzeDuur", 0);
			activiteit.setProperty("BeginLaatstePauze", null);
			datastore.put(activiteit);
	}

	public void createSport(String googleAccount, Date starttijd,
			String sport) {
		// TODO type sport
		Sport sportje = new Sport();
		sportje.setStartTijd(starttijd);
		getStudent(googleAccount).addActiviteit(sportje);
		Entity activiteit = new Entity("Activiteit");
			activiteit.setProperty("Type", "sport");
			activiteit.setProperty("Starttijd", starttijd);
			activiteit.setProperty("Gestopt", false);
			activiteit.setProperty("Student", googleAccount);
			activiteit.setProperty("Sport", sport);
			activiteit.setProperty("PauzeDuur", 0);
			activiteit.setProperty("BeginLaatstePauze", null);
			datastore.put(activiteit);
	}

	public void createSlaap(String googleAccount, int duur) {
		Slaap slaap = new Slaap();
		Date starttijd = Calendar.getInstance().getTime();
		slaap.setStartTijd(starttijd);
		slaap.setGestopt(true);
		getStudent(googleAccount).addActiviteit(slaap);
		Entity activiteit = new Entity("Activiteit");
			activiteit.setProperty("Type", "slaap");
			activiteit.setProperty("Duur", duur);
			activiteit.setProperty("Student", googleAccount);
			activiteit.setProperty("Starttijd" , starttijd);
			activiteit.setProperty("Gestopt",true);
			datastore.put(activiteit);
	}

	public void beginPauze(String googleAccount, Date beginPauze) {
		System.out.println("We pauzeren!");
		System.out.println("beginPauze: "+beginPauze);
		for(int i = 0; i<getStudent(googleAccount).getActiviteiten().size();i++){
			if(!getStudent(googleAccount).getActiviteit(i).getGestopt()){
				getStudent(googleAccount).getActiviteit(i).setBeginLaatstePauze(beginPauze);
			}
		}
		Query q = new Query("Activiteit");
		q.addFilter("Student", Query.FilterOperator.EQUAL, googleAccount);
		PreparedQuery pq = datastore.prepare(q);
		for (Entity result : pq.asIterable()) {
			if (!(Boolean) result.getProperty("Gestopt")) {
				result.setProperty("BeginLaatstePauze", beginPauze);
				datastore.put(result);
			}
		}
	}
	
	public void hervat(String googleAccount, Date eindePauze){
		for(int i = 0; i<getStudent(googleAccount).getActiviteiten().size();i++){
			if(!getStudent(googleAccount).getActiviteiten().get(i).getGestopt()){
				long duurInMin = getStudent(googleAccount).getActiviteiten().get(i).getPauzeDuurInMin() + (eindePauze.getTime() - getStudent(googleAccount).getActiviteiten().get(i).getBeginLaatstePauze().getTime())/60000;
				getStudent(googleAccount).getActiviteit(i).setPauzeDuur(duurInMin);
			}
		}
		
		Query q = new Query("Activiteit");
		q.addFilter("Student", Query.FilterOperator.EQUAL, googleAccount);
		PreparedQuery pq = datastore.prepare(q);
		for (Entity result : pq.asIterable()) {
			if (!(Boolean) result.getProperty("Gestopt")) {
				Date begin = (Date) result.getProperty("BeginLaatstePauze");
				long duurInMin = ((Long) result.getProperty("PauzeDuur")) + (- begin.getTime() + eindePauze.getTime())/60000;
				Date vandaag = Calendar.getInstance().getTime();
				long min = vandaag.getTime();
				result.setProperty("PauzeDuur",duurInMin);
				datastore.put(result);
			}
		}
	}

	public void stopSlaap(int rating, Date stoptijd, String googleAccount) {
		for (int i = 0; i < getStudent(googleAccount).getActiviteiten().size(); i++) {
			Activiteit activiteit = getStudent(googleAccount).getActiviteiten().get(i);
			if (!activiteit.getGestopt()) {
				activiteit.setRating(rating);
				activiteit.setStopTijd(stoptijd);
				activiteit.setGestopt(true);
			}
		}
		Query q = new Query("Activiteit");
		q.addFilter("Student", Query.FilterOperator.EQUAL, googleAccount);
		PreparedQuery pq = datastore.prepare(q);
		for (Entity result : pq.asIterable()) {
			if (!(Boolean) result.getProperty("Gestopt")) {
				result.setProperty("Stoptijd", stoptijd);
				result.setProperty("Rating", rating);
				result.setProperty("Gestopt", true);
				datastore.put(result);
			}
		}
	}

	public void stopSport(int rating, Date stoptijd, String googleAccount) {
		for (int i = 0; i < getStudent(googleAccount).getActiviteiten().size(); i++) {
			Activiteit activiteit = getStudent(googleAccount).getActiviteiten()
					.get(i);
			if (!activiteit.getGestopt()) {
				activiteit.setRating(rating);
				activiteit.setStopTijd(stoptijd);
				activiteit.setGestopt(true);
			}
		}
		Query q = new Query("Activiteit");
		q.addFilter("Student", Query.FilterOperator.EQUAL, googleAccount);
		PreparedQuery pq = datastore.prepare(q);
		for (Entity result : pq.asIterable()) {
			if((Boolean) result.getProperty("Gestopt") != null){
				if (!(Boolean) result.getProperty("Gestopt") && ((String) result.getProperty("Type")).equals("sport")) {
					result.setProperty("Stoptijd", stoptijd);
					result.setProperty("Rating", rating);
					result.setProperty("Gestopt", true);
					datastore.put(result);
				}
			}
		}
	}

	public void stopStudie(int rating, Date stoptijd, int aantaloef,
			int aantalpag, boolean theorie, boolean oef, String googleAccount) {
		for (int i = 0; i < getStudent(googleAccount).getActiviteiten().size(); i++) {
			Activiteit activiteit = getStudent(googleAccount).getActiviteiten().get(i);
			if (!activiteit.getGestopt()) {
				Studie studie = (Studie) getStudent(googleAccount).getActiviteiten().get(i);
				getStudent(googleAccount).getActiviteiten().remove(i);
				studie.setRating(rating);
				studie.setStopTijd(stoptijd);
				studie.setAantalOef(aantaloef);
				studie.setAantalPag(aantalpag);
				studie.setOefeningen(oef);
				studie.setTheorie(theorie);
				studie.setStopTijd(stoptijd);
				studie.setGestopt(true);
				getStudent(googleAccount).getActiviteiten().add(studie);
			}
		}
		Query q = new Query("Activiteit");
		q.addFilter("Student", Query.FilterOperator.EQUAL, googleAccount);
		PreparedQuery pq = datastore.prepare(q);
		for (Entity result : pq.asIterable()) {
			if((Boolean) result.getProperty("Gestopt") != null){
				if (!(Boolean) result.getProperty("Gestopt") && ((String) result.getProperty("Type")).equals("studie")) {				
					result.setProperty("Stoptijd", stoptijd);
					result.setProperty("Rating", rating);
					result.setProperty("Gestopt", true);
					result.setProperty("AantalOef",aantaloef);
					result.setProperty("AantalPag", aantalpag);
					result.setProperty("Theorie",theorie);
					result.setProperty("Oefeningen",oef);
					datastore.put(result);
					// terug in datastore steken, of wordt die dan gedupliceerd??
				}
			}
		}
	}
	
	public void setNieuweInstellingen(String googleAccount, String voornaam, String achternaam, List<Vak> vakken){
		//past de lijst aan
		System.out.println("Binnen in setNieuweNieuweInstellingen");
		Student curUser = getStudent(googleAccount);
		getStudent(googleAccount).setVakken(null);
		getStudent(googleAccount).setVoornaam(null);
		getStudent(googleAccount).setAchternaam(null);
		getStudent(googleAccount).setVakken(vakken);
		getStudent(googleAccount).setVoornaam(voornaam);
		getStudent(googleAccount).setAchternaam(achternaam);
		System.out.println("Grootte vakkenlijst huidige student "+getStudent(googleAccount).getVakken().size());

		//past de datastore aan
		Query q = new Query("Student");
		q.addFilter("GoogleAccount", Query.FilterOperator.EQUAL, googleAccount);
		PreparedQuery pq = datastore.prepare(q);
		for (Entity result : pq.asIterable()) {
			int k = 0;
			int i = 0;
			while (k != 1) {
				if (result.getProperty("Vak" + i) == null) {
					k = 1;
				} else {
					result.setProperty("Vak"+i, null);
				}
				i++;
			}
			result.setProperty("Achternaam", achternaam);
			result.setProperty("Voornaam",voornaam);
			for(int j=0; j<vakken.size(); j++){
				result.setProperty("Vak"+j, vakken.get(j).getNaam());
			}
			//datastore.delete(result.getKey());
			datastore.put(result);
		}
	}
	
}
